package com.kun.video.thread;

import org.jetbrains.annotations.NotNull;

import java.util.concurrent.*;

/**
 * 优先级线程池执行器
 * <p>
 * 扩展标准ThreadPoolExecutor，提供以下增强功能：
 * 1. 强制使用PriorityBlockingQueue作为任务队列
 * 2. 自动包装任务为PriorityFutureTask
 * 3. 校验任务类型确保优先级逻辑生效
 * </p>
 *
 * @author gzc
 * @since 2025/2/3
 */
public class PriorityThreadPoolExecutor extends ThreadPoolExecutor {

    //------------------------- 构造函数 -------------------------

    /**
     * 核心构造函数
     *
     * @param corePoolSize      核心线程数
     * @param maxPoolSize       最大线程数
     * @param keepAliveTime     非核心线程空闲存活时间
     * @param unit              时间单位
     * @param workQueue         任务队列（必须为PriorityBlockingQueue）
     * @param taskThreadFactory 线程工厂
     * @throws IllegalArgumentException 如果队列类型不匹配
     */
    public PriorityThreadPoolExecutor(int corePoolSize,
                                      int maxPoolSize,
                                      long keepAliveTime,
                                      @NotNull TimeUnit unit,
                                      @NotNull PriorityBlockingQueue<Runnable> workQueue,
                                      @NotNull ThreadFactory taskThreadFactory) {
        this(corePoolSize, maxPoolSize, keepAliveTime, unit,
                workQueue, taskThreadFactory, new CallerRunsPolicy());
    }

    /**
     * 全参数构造函数（可指定拒绝策略）
     */
    public PriorityThreadPoolExecutor(int corePoolSize,
                                      int maxPoolSize,
                                      long keepAliveTime,
                                      @NotNull TimeUnit unit,
                                      @NotNull PriorityBlockingQueue<Runnable> workQueue,
                                      @NotNull ThreadFactory taskThreadFactory,
                                      RejectedExecutionHandler rejectedExecutionHandler) {
        super(corePoolSize, maxPoolSize, keepAliveTime, unit,
                workQueue, taskThreadFactory, rejectedExecutionHandler);
        validateQueueType(workQueue);
    }

    //------------------------- 核心方法 -------------------------

    /**
     * 重写任务包装方法
     *
     * @param runnable 必须为PrioritizedTask类型
     * @return 包装后的PriorityFutureTask
     * @throws IllegalStateException 如果任务类型非法
     */
    @Override
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        if (!(runnable instanceof PrioritizedTask)) {
            throw new IllegalStateException("非法任务类型: " + runnable.getClass().getName());
        }
        return new PriorityFutureTask<>(runnable, value);
    }

    /**
     * 提交任务（类型校验增强）
     *
     * @param runnable 必须为PrioritizedTask类型
     * @throws IllegalArgumentException 如果任务类型非法
     */
    @Override
    public Future<?> submit(@NotNull Runnable runnable) {
        validateTaskType(runnable);
        return super.submit(runnable);
    }

    //------------------------- 校验方法 -------------------------

    /**
     * 校验队列类型必须为PriorityBlockingQueue
     */
    private void validateQueueType(BlockingQueue<Runnable> queue) {
        if (!(queue instanceof PriorityBlockingQueue)) {
            throw new IllegalArgumentException("工作队列必须为PriorityBlockingQueue，实际类型：" +
                    queue.getClass().getSimpleName());
        }
    }

    /**
     * 校验任务类型必须为PrioritizedTask
     */
    private void validateTaskType(Runnable task) {
        if (!(task instanceof PrioritizedTask)) {
            throw new IllegalArgumentException("仅支持PrioritizedTask类型任务，实际类型：" +
                    task.getClass().getSimpleName());
        }
    }
}